<template>
  <view
    :style="[styles]"
    :class="classNameList"
    @touchstart="touchStart"
    @touchmove="touchMove"
    @touchend="touchEnd"
  >
    <view id="x-draggable-content" class="_content">
      <slot />
    </view>
  </view>
</template>

<script>
export default {
  name: 'XDraggable',
  components: {},
  props: {
    disabled: {
      type: Boolean,
      default: false
    },
    zIndex: {
      type: Number,
      default: 1000
    },
    x: {
      type: Number,
      default: 0
    },
    y: {
      type: Number,
      default: 0
    }
  },
  data() {
    return {
      dragging: false,
      windowInfo: uni.getWindowInfo() || {},
      width: 0,
      height: 0,
      left: 0,
      top: 0,
      pageX: 0,
      pageY: 0
    };
  },
  computed: {
    styles() {
      return {
        zIndex: this.zIndex,
        left: this.pageX + 'px',
        top: this.pageY + 'px'
      };
    },
    classNameList() {
      const name = ['x-draggable'];
      // 悬浮
      if (!this.disabled) {
        name.push('is-fixed');
      }
      return name.join(' ');
    }
  },
  watch: {
    x(value) {
      this.left = value;
      this.pageX = value;
    },
    y(value) {
      this.top = value;
      this.pageY = value;
    },
    disabled(value) {
      if (!value) {
        this.$nextTick(() => {
          this.setInfo();
        });
      }
    }
  },
  created() {
    this.left = this.x;
    this.pageX = this.x;
    this.top = this.y;
    this.pageY = this.y;
  },
  mounted() {},
  methods: {
    // 获取navigation信息
    setInfo() {
      const query = uni.createSelectorQuery().in(this);
      query.select('#x-draggable-content').boundingClientRect(data => {
        this.width = data.width;
        this.height = data.height;
      }).exec();
    },
    // 触摸开始事件
    touchStart(e) {
      if (this.disabled) return;
      this.dragging = true;
      const { pageX, pageY } = e.changedTouches[0];
      this.left = pageX - this.left;
      this.top = pageY - this.top;
    },
    // 手指触摸后移动
    touchMove(e) {
      if (this.disabled || !this.dragging) return;
      const { pageX, pageY } = e.changedTouches[0];
      this.pageX = pageX - this.left;
      this.pageY = pageY - this.top;
    },
    // 手指触摸离开
    touchEnd() {
      if (this.disabled || !this.dragging) return;
      const { windowWidth, windowHeight } = this.windowInfo;
      // x 边界
      if (this.pageX <= 10) {
        this.pageX = 10;
      } else if (this.pageX + this.width > (windowWidth - 10)) {
        this.pageX = windowWidth - this.width - 10;
      }

      // y 边界
      if (this.pageY <= 100) {
        this.pageY = 100;
      } else if (this.pageY + this.height > (windowHeight - 100)) {
        this.pageY = windowHeight - this.height - 100;
      }

      this.left = this.pageX;
      this.top = this.pageY;
      this.dragging = false;
    }
  }
};
</script>

<style lang="scss">
  .x-draggable{
    &.is-fixed{
      position: fixed;
    }
  }
</style>
